package edu.hawaii.halealohacli.command;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Timer;
import org.wattdepot.client.NotAuthorizedException;
import org.wattdepot.client.WattDepotClient;
import org.wattdepot.client.WattDepotClientException;
import org.wattdepot.resource.source.jaxb.Source;
/**
 * Monitor-power class that gets the current power based on a 
 * tower or lounge name at a given interval.
 *
 * @author Sean Chung
 */
public class MonitorPower implements Command {
  private String source;
  private String output;
  private int interval = 10;
  private String command = "monitor-power";
  private String arguments = "[tower | lounge] [interval]";
  private int numParams = 0; // Not needed, but must be set to implement Command.
  private String help = "This command prints out a timestamp and the current power for " +
      "[tower | lounge] every [interval] seconds.  [interval] is an optional integer " +
      "greater than 0 and defaults to 10 seconds. Entering any character (such as a " +
      "carriage return) stops this monitoring process and returns the user to the command loop.";
  
  @Override
  public String run(String[] input, WattDepotClient client) {   
    int i = 0;
    String[] sourceNames = new String[100];
    int inputLength = input.length;
    
    // Make sure user entered something first. 
    if (input.length > 1) {
      this.source = input[1];
    }
    else {
      return "No arguments entered. Need 1 or 2. Try again";
    }
    
    // Put all source names for client in array.     
    try {
      List<Source> sources;
      sources = client.getSources();
      
      for (Source source : sources) {
        sourceNames[i] = source.getName();
        i++;          
      }
    }
    catch (NotAuthorizedException e) {
      output = "You are not authorized to access this client.";
    }
    catch (WattDepotClientException e) {
      output = "An unexpected error occured. Please try again.";
    }
    
    // Check if source is a valid source by comparing to array of names.
    if (Arrays.asList(sourceNames).contains(this.source)) {  
      
      // No interval value entered. 
      if (inputLength == 2) {
        runMonitor(this.source, client);
      }    
      // Try to get the assumed entered interval value.
      else if (inputLength == 3) {
        try {
          interval = Integer.parseInt(input[2]);
        }
        catch (NumberFormatException e) {
          return "\"" + input[2] + "\"" + " entered as an interval. " +
              "Please enter only integers.";
        }
        
        // Make sure interval entered is greater than 0.
        if (interval > 0) {
          runMonitor(this.source, client);
        }
        else {
          output = "\"" + input[2] + "\"" + " entered as an interval. " +
              "Please enter only integer values greater than 0.";
        }
      }
      else {
        output = "Wrong number of arguments entered. Received " + 
        "\"" + (inputLength - 1) + "\"" + ". Need 1 or 2. Try again.";
      }
    }
    else {
      output = "\"" + input[1] + "\" is not a valid source.";
    }
    return output;
  }

  @Override
  public String getCommand() {
    return command;
  }
  
  // This method is not active in this case, so there can be optional
  // arguments, without causing an error.
  // Changes can be found in CommandProcessor.java file.
  @Override
  public int getNumParams() {
    return numParams;
  }

  @Override
  public String getHelp() {
    return command + " " + arguments + "\n" + help;
  }

  /**
   * Starts the monitoring task and continues until user presses <Enter> key.
   * @param source the source.
   * @param client the client.
   */
  public void runMonitor(String source, WattDepotClient client) {    
    System.out.println("Beginning monitoring of " + "\"" + this.source + "\"" + 
        " at " + interval + " second intervals. Press <Enter> to stop");
    
    // Create new timer and monitorTask to run.
    Timer timer = new Timer();
    MonitorTask monitorTask = new MonitorTask(source, client);
    monitorTask.run();
    
    // Intervals are in milliseconds. Need to multiple by 1000 to get seconds.
    interval *= 1000;
    timer.scheduleAtFixedRate(monitorTask, interval, interval);
    try {
      while (System.in.available() == 0) {      
        Thread.sleep(500);     
      }
    }
    catch (IOException e) {
      System.out.println("Input Error. Please try again.");
    }
    catch (InterruptedException e) {
      System.out.println("Error. Please try again.");
    }    
    timer.cancel();
    output = "Monitoring has ended. Returning to main program.";
  }
}